#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	int x=0;bool f=0;char ch=getchar();
	while(ch<'0'||ch>'9')f^=(ch=='-'),ch=getchar();
	while('0'<=ch&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
const int Maxn=1e5+5,inf=1e18;
int n,m,q;
int c[Maxn];
int a[Maxn][10];
struct Tree{
	int val[6][6][2][2];
}t[Maxn<<2],ko;
inline Tree update(Tree ls,Tree rs){
	Tree res=ko;
//	int val=0;
	for(int i=1;i<=m;i++)for(int j=1;j<=m;j++)
		for(int k=1;k<=m;k++){
			res.val[i][j][0][0]=max({res.val[i][j][0][0],ls.val[i][k][0][0]+rs.val[k][j][0][0],ls.val[i][k][0][1]+rs.val[k][j][1][0]});
			res.val[i][j][1][0]=max({res.val[i][j][1][0],ls.val[i][k][1][0]+rs.val[k][j][0][0],ls.val[i][k][1][1]+rs.val[k][j][1][0]});
			res.val[i][j][0][1]=max({res.val[i][j][0][1],ls.val[i][k][0][0]+rs.val[k][j][0][1],ls.val[i][k][0][1]+rs.val[k][j][1][1]});
			res.val[i][j][1][1]=max({res.val[i][j][1][1],ls.val[i][k][1][0]+rs.val[k][j][0][1],ls.val[i][k][1][1]+rs.val[k][j][1][1]});
//			val=max(val,res.val[i][j][0][0]);
		}
//	for(int i=1;i<=m;i++)for(int j=1;j<=m;j++)res.val[i][j][0][0]=val;
	return res;
}
void build(int x,int l,int r){
	if(l==r){
		t[x]=ko;
		for(int i=1;i<=m;i++){
			for(int j=1;j<=m;j++)t[x].val[i][j][0][0]=a[l][c[l]];
			t[x].val[i][i][1][1]=a[l][i];
		}
		for(int j=1;j<=m;j++){
			t[x].val[j][c[l]][0][1]=t[x].val[c[l]][j][1][0]=a[l][c[l]];
			t[x].val[j][c[l]][0][0]=t[x].val[c[l]][j][0][0]=a[l][c[l]];
		}
		for(int j=0;j<2;j++)for(int k=0;k<2;k++)t[x].val[c[l]][c[l]][j][k]=a[l][c[l]];
//		if(l==3){
//			printf("vdwvdgerg %d\n",t[x].val[3][3][1][1]);
//		}
		return;
	}int mid=l+r>>1;
	build(x<<1,l,mid);build(x<<1|1,mid+1,r);
	t[x]=update(t[x<<1],t[x<<1|1]);
//	if(l==1&&r==5||l==6&&r==10);else return;
//	printf("[%d,%d]:\n",l,r);
//	for(int i=1;i<=m;i++){
//		for(int g=1;g<=m;g++){
//			printf("%d %d: ",i,g);
//			for(int j=0;j<2;j++)
//				for(int k=0;k<2;k++){
//					printf("(%d,%d)=%lld ",j,k,t[x].val[i][g][j][k]);
//				}
//			puts("");
//		}
//	}
}
void change(int x,int l,int r,int d){
	if(l==r){
		t[x]=ko;
		for(int i=1;i<=m;i++){
			for(int j=1;j<=m;j++)t[x].val[i][j][0][0]=a[l][c[l]];
			t[x].val[i][i][1][1]=a[l][i];
		}
		for(int j=1;j<=m;j++){
			t[x].val[j][c[l]][0][1]=t[x].val[c[l]][j][1][0]=a[l][c[l]];
			t[x].val[j][c[l]][0][0]=t[x].val[c[l]][j][0][0]=a[l][c[l]];
		}
		for(int j=0;j<2;j++)for(int k=0;k<2;k++)t[x].val[c[l]][c[l]][j][k]=a[l][c[l]];
		return;
	}int mid=l+r>>1;
	if(mid>=d)change(x<<1,l,mid,d);
	else change(x<<1|1,mid+1,r,d);
	t[x]=update(t[x<<1],t[x<<1|1]);
}
Tree query(int x,int l,int r,int L,int R){
	if(L<=l&&r<=R)return t[x];
	int mid=l+r>>1;
	if(mid>=L&&mid<R)return update(query(x<<1,l,mid,L,R),query(x<<1|1,mid+1,r,L,R));
	if(mid>=L)return query(x<<1,l,mid,L,R);
	return query(x<<1|1,mid+1,r,L,R);
}
signed main(){
	freopen("paint.in","r",stdin);
	freopen("paint.out","w",stdout);
	n=read();m=read();q=read();
	for(int i=1;i<=m;i++)for(int g=1;g<=m;g++)for(int j=0;j<2;j++)for(int k=0;k<2;k++)ko.val[i][g][j][k]=-inf;
	for(int i=1;i<=n;i++)c[i]=read();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)a[i][j]=read();
	}build(1,1,n);
	int last=t[1].val[1][1][0][0];
	printf("%lld\n",last);
//	
//	for(int i=1;i<=n;i++){
//		printf("f[%d]=%d\n",i,query(1,1,n,1,i).val[1][1][0][0]);
//	}
	
	while(q--){
		int op=read(),x=read()^last,y=read()^last;
//		printf("dododo %d %d %d\n",op,x,y);
		if(op==1){
			c[x]=y;change(1,1,n,x);
		}else{
			if(x>y)swap(x,y);
			Tree tmp=query(1,1,n,x,y);
			last=tmp.val[1][1][0][0];
			printf("%lld\n",last);
		}
	}
	return 0;
}
/*
10 3 0
3 2 2 3 3 2 3 1 1 3
1 6 10 
10 2 2 
7 10 5 
5 8 1 
5 10 4 
7 3 6 
6 1 4 
6 10 7 
1 6 5 
2 1 6 


5 3 0
2 3 1 1 3
7 3 6 
6 1 4 
6 10 7 
1 6 5 
2 1 6 
*/
